//
//  DefaultSportCalculateEngine.swift
//  LKSportSDKSportManager
//
//  Created by KuaiKuai on 2023/8/25.
//

import Foundation
public class DefaultSportCalculateEngine: NSObject, SportCalculateEngineInterface{
    // 运动记录
    public var sportRecord: SportRecordModel?
    public var user: UserConfig
    public weak var delegate: SportDataCalculateEngineDelegate?
    // 当前心率等级
    var currentHeartRateLevel: SportHeartRateLevel = .l1
    // 当前火力全开
    var currentFireState = false
    /// 心率低次数
    var heartRateLowCount: Int = 0
    /// 心率正常次数
    var heartRateNormalCount: Int = 0
    /// 心率低次数
    var heartRateHightCount: Int = 0
    /// 火力全开计时器
    var fireTimer: Timer?
    /// l3连续次数
    var l3Count: Int = 0
   public init(user: UserConfig) {
        self.user = user
    }
    
   public func calculate(sportConfig: SportConfig, data: SportDataModel) {
        
       guard let sportRecord = self.sportRecord else {
           return
       }
        // 已经有运动记录
       let countModel = SportDataCountModel(recorduuid: sportRecord.uuid, id: sportConfig.id, name: sportConfig.name, code: sportConfig.code)
        if let configVal = sportConfig.heartRateConfig {
           let singlRange =  configVal.ranges.first { hrRangeConfig in
                if let aVal = hrRangeConfig.values.first {
                    return (data.heartRate >= aVal.min && data.heartRate <= aVal.max)
                }else {
                    return false
                }
            }
            guard let rangeVal = singlRange else {
                print("未找到心率对应区间")
                return
            }
            if let rVal = rangeVal.values.first {
                print("心率：\(data.heartRate) 心率区间得分：\(rangeVal.score) 心率区间[\(rVal.min),\(rVal.max)]")
                let heartRateScore =  Int(rangeVal.score * currentHeartRateLevel.scoreFactor)
                countModel.heartRate = data.heartRate
                countModel.heartRateLevel = currentHeartRateLevel
                countModel.heareRateRange = rangeVal.type
                countModel.isFireState = currentFireState
                countModel.heartRateScore = heartRateScore
                levelCheck(heartRateRange: rangeVal.type, currentSportRecord: sportRecord)
            }
        }
       
       if let instensityConfigVal = sportConfig.intensityConfig {
           let singlRange =  instensityConfigVal.ranges.first { intensityRangeConfig in
                if let aVal = intensityRangeConfig.values.first {
                    return (data.sportIntensity >= aVal.min && data.sportIntensity <= aVal.max)
                }else {
                    return false
                }
            }
            
            guard let rangeVal = singlRange else {
                print("未找到动作强度对应区间")
                return
            }
           //print("实际动作强度：\(data.sportIntensity)，实际动作类型:\(rangeVal.type)")
           let actionScore = Int(rangeVal.score)
           countModel.actionScore = actionScore
           countModel.actionQuality = rangeVal.quality
           countModel.actionIntensity = data.sportIntensity
       }
       
       if let burnConfigVal = sportConfig.burnConfig {
           countModel.burn = burnConfigVal.burn
           //每秒消耗的最小热量
           let minCalorie = 30.0
           //所占用百分比
           let percentage = Double(burnConfigVal.burn) / minCalorie
           //锻炼系数
           let exerciseFactor: Double = 1.0
           let sum = Double(burnConfigVal.score) * percentage * exerciseFactor
           countModel.burnScore = Int(sum)
       }
       
       let score1 = Double(countModel.heartRateScore) * 0.4
       let score2 = Double(countModel.burnScore) * 0.4
       let score3 = Double(countModel.actionScore) * 0.2
       countModel.totalScore = Int((score1 + score2 + score3) * (countModel.isFireState ? 1.1 : 1.0))
       
       sportRecord.duration += 1
       sportRecord.countDatas.append(countModel)
       sportRecord.burn += countModel.burn
       sportRecord.burnScore += countModel.burnScore
       sportRecord.actionScore += countModel.actionScore
       sportRecord.totalScore += countModel.totalScore
       sportRecord.heartRateScore += countModel.heartRateScore
       delegate?.calculateCompletion(user: user, record: sportRecord)
       
    }

    func levelCheck(heartRateRange: Int, currentSportRecord: SportRecordModel) {
        
        switch heartRateRange {
            
        case HeartRateRangeType.none.rawValue:
            break
        case HeartRateRangeType.gray.rawValue,HeartRateRangeType.blue.rawValue,HeartRateRangeType.yellow.rawValue:
            heartRateLowCount += 1
            heartRateNormalCount = 0
            heartRateHightCount = 0
            break
        case HeartRateRangeType.green.rawValue,HeartRateRangeType.orange.rawValue:
            heartRateLowCount = 0
            heartRateNormalCount += 1
            heartRateHightCount = 0
            break
        case HeartRateRangeType.red.rawValue:
            heartRateLowCount = 0
            heartRateNormalCount = 0
            heartRateHightCount += 1
           break
        default:
            break
        }
        
        switch currentHeartRateLevel {
        case .l0:
            if heartRateNormalCount >= 10 {
                currentHeartRateLevel = .l1
                heartRateNormalCount = 0
                currentSportRecord.l1Count += 1
                delegate?.heartRateLevelUpgrad(user: self.user, level: currentHeartRateLevel)
            }
        case .l1:
            if heartRateNormalCount >= 20 {
                currentHeartRateLevel = .l2
                heartRateNormalCount = 0
                currentSportRecord.l2Count += 1
                delegate?.heartRateLevelUpgrad(user: self.user, level: currentHeartRateLevel)
            }
        case .l2:
            if heartRateNormalCount >= 40 {
                currentHeartRateLevel = .l3
                heartRateNormalCount = 0
                currentSportRecord.l3Count += 1
                l3Count = 1
                currentFireState = true
                delegate?.heartRateLevelUpgrad(user: self.user, level: currentHeartRateLevel)
                startFireTimer()
                delegate?.onEnterFireState(user: self.user)
            }
            
        case .l3:
            if heartRateNormalCount >= 40 {
                heartRateNormalCount = 0
                currentSportRecord.l3Count += 1
                l3Count += 1
                delegate?.heartRateLevelUpgrad(user: self.user, level: currentHeartRateLevel)
            }
        
        }
        
        if (heartRateLowCount >= 10) || (heartRateHightCount >= 5) {
            currentHeartRateLevel = .l0
            currentFireState = false
            delegate?.heartRateLevelUpgrad(user: self.user, level: currentHeartRateLevel)
            fireTimer?.invalidate()
            fireTimer = nil
            delegate?.onExitFireState(user: self.user)
        }
        
    }
    
    func startFireTimer() {
        fireTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
            guard let weakself = self else {
                return
            }
            weakself.sportRecord?.fireDuration += 1
        }
        RunLoop.current.add(fireTimer!, forMode: .common)
    }
    
}
